import httpx
import json
import time
import logging
from typing import Dict, Any, AsyncGenerator

from fastapi import HTTPException
from fastapi.responses import StreamingResponse

from app.core.config import settings
from app.providers.base_provider import BaseProvider

logger = logging.getLogger(__name__)

class GptdeProvider(BaseProvider):
    def __init__(self):
        self.api_url = "https://gptde.de/wp-admin/admin-ajax.php"
        # 在启动时检查关键配置是否存在
        if not all([settings.COOKIE, settings.NONCE, settings.CLIENT_ID]):
            raise ValueError("配置错误: .env 文件中缺少 COOKIE, NONCE, 或 CLIENT_ID。")
        
        self.client = httpx.AsyncClient(timeout=settings.API_REQUEST_TIMEOUT)

    async def chat_completion(self, request_data: Dict[str, Any]) -> StreamingResponse:
        try:
            headers = self._prepare_headers()
            payload = self._prepare_payload(request_data)
            
            async def stream_generator() -> AsyncGenerator[bytes, None]:
                try:
                    async with self.client.stream("POST", self.api_url, headers=headers, data=payload) as response:
                        response.raise_for_status()
                        logger.info("成功连接到上游服务并开始流式传输。")
                        async for chunk in response.aiter_bytes():
                            yield chunk
                except httpx.HTTPStatusError as e:
                    error_content = await e.response.aread()
                    error_msg = f"上游服务器错误: {e.response.status_code} - {error_content.decode()}"
                    logger.error(error_msg)
                    yield self._create_error_chunk(error_msg)
                except Exception as e:
                    error_msg = f"流式传输时发生未知错误: {e}"
                    logger.error(error_msg, exc_info=True)
                    yield self._create_error_chunk(error_msg)

            return StreamingResponse(stream_generator(), media_type="text/event-stream")

        except Exception as e:
            logger.error(f"在准备请求时发生错误: {e}", exc_info=True)
            raise HTTPException(status_code=500, detail=f"内部服务器错误: {e}")

    def _prepare_headers(self) -> Dict[str, str]:
        """准备请求头，直接使用 settings 中的配置。"""
        return {
            "authority": "gptde.de",
            "accept": "*/*",
            "accept-language": "zh-CN,zh;q=0.9,en;q=0.8",
            "content-type": "application/x-www-form-urlencoded; charset=UTF-8",
            "cookie": settings.COOKIE,
            "origin": "https://gptde.de",
            "referer": "https://gptde.de/?via=topaitools",
            "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36",
        }

    def _prepare_payload(self, request_data: Dict[str, Any]) -> Dict[str, Any]:
        """准备请求体，直接使用 settings 中的配置。"""
        messages = request_data.get("messages", [])
        
        history = []
        for msg in messages:
            role = msg.get("role")
            content = msg.get("content", "")
            if role == "user":
                history.append({"id": "", "text": f"Human: {content}"})
            elif role == "assistant":
                # 注意：根据抓包信息，历史记录中的 AI 回复需要一个 id
                # 这里我们用一个占位符，实际可能需要更复杂的逻辑来获取真实 id
                history.append({"id": "some_id", "text": f"AI: {content}"})
        
        last_user_message = next((msg["content"] for msg in reversed(messages) if msg["role"] == "user"), "")

        return {
            "_wpnonce": settings.NONCE,
            "post_id": "110",
            "url": "https://gptde.de",
            "action": "wpaicg_chat_shortcode_message",
            "message": last_user_message,
            "bot_id": "0",
            "chatbot_identity": "shortcode",
            "wpaicg_chat_history": json.dumps(history[:-1]),
            "wpaicg_chat_client_id": settings.CLIENT_ID,
            "chat_id": "" 
        }

    async def get_models(self) -> Dict:
        """返回在 config 中定义的模型列表。"""
        return {
            "object": "list",
            "data": [{"id": name, "object": "model", "created": int(time.time()), "owned_by": "system"} for name in settings.KNOWN_MODELS]
        }

    def _create_error_chunk(self, message: str) -> bytes:
        """创建一个标准的 OpenAI 错误信息块。"""
        error_payload = {
            "id": f"chatcmpl-error-{int(time.time())}",
            "object": "chat.completion.chunk",
            "created": int(time.time()),
            "model": "error-model",
            "choices": [{"index": 0, "delta": {"content": f"\n\n【gptde-2api 错误】\n{message}\n"}, "finish_reason": "stop"}]
        }
        return f"data: {json.dumps(error_payload)}\n\ndata: [DONE]\n\n".encode('utf-8')
